#include <iostream>

#include "separation.h"

using namespace std;

//函数定义和函数声明
//声明和定义分离又是方便维护
//看xxx.h了解框架设计和基本功能
//看xxx.cpp了解具体实现细节

//函数模板分离编译
//int main()
//{
//    //正常的函数分离编译是没有问题
//    function_1(2); //链接的时候去其他文件找的函数地址
//    
//    //如果是函数模板分离编译就会出现问题
//    //具体的原因如下
//    //我们先来回顾一下,程序的编译链接
//    //1.预处理->有文件展开\条件编译\宏替换\去掉注释
//    //生成  test.i  separation.i
//    //2.编译->检查语法问题,没有问题就生成汇编代码
//    //生成  test.s  separation.s
//    //3.汇编->生成符号表,把汇编代码转化成二进制机器码
//    //生成  test.o  separation.o
//    //4.链接->符号表的合并和符号表的重定位
//    //生成  test 
//    
//    //普通的函数分离编译没有问题是因为
//    //最后链接的时候,会根据符号表找到函数的位置
//    //但是如果是函数模板分离编译,由于函数模板的声明可以知道爽么类型
//    //但是函数模板的定义不知道类型,却不能实例化
//    //我们知道函数的第一句就是函数的地址,所以找不到函数的地址
//    //当我们显示实例化一份的时候,就可以解决这个问题
//    
//    //解决方式1:函数模板显示实例化
//    //function_2(3);
//    //function_2(2.3);
//
//    //解决方式2:函数模板声明和定义不分离
//    //能够解决的这个问题的原因是:
//    //使用这个函数模板的地方,头文件展开后,直接就有模板定义
//    //那么就可以直接实例化,那么实例化后,就可以直接填上函数调用地址
//    //不需要链接去找了
//    function_2(3);  //编译的时候就确定地址了
//    function_2(2.3);
//
//
//    
//    return 0;
//}

//类模板分离编译
int main()
{
    A<int>* pa; //头文件有声名,可以用类型
    //解决方法:
    //1.头文件里面显式实例化出类或者显式实例化出函数
    //2.声明和定义不分离
    A<int> a;   //同样的这里调用构造函数,链接不上
    A<double> b;


    return 0;
}

//最后总结一下模板的优点和缺点
//优点:
//1.模板复用了代码,节省了资源,更快的迭代开发,c++的标准模板库(STL)由此诞生
//2.增强了代码的灵活性

//缺陷:
//1.模板会导致代码膨胀问题,也会导致编译时间变长,因为实例化是需要时间的
//出现模板编译错误是,错误信息非常凌乱,不容易定位
